package pcjavanet.mybatis.plugin;

import static org.mybatis.generator.internal.util.messages.Messages.getString;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import org.apache.log4j.Logger;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.Parameter;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.Document;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;

public class PostgresqlPagePlugin extends PluginAdapter {
	protected static Logger logger =Logger.getLogger(PostgresqlPagePlugin.class);
	
	public boolean validate(List<String> arg0) {

		return true;
	}
//    private void addField(String fieldName, FullyQualifiedJavaType fieldType,  
//            TopLevelClass topLevelClass) {  
//        Field tmpField = new Field(fieldName, fieldType);  
//        tmpField.setVisibility(JavaVisibility.PRIVATE);  
//        topLevelClass.addField(tmpField);  
//  
//        Method setMethod = new Method();  
//        setMethod.setName("set" + fieldName.toUpperCase().substring(0, 1)  
//                + fieldName.substring(1));  
//        Parameter param = new Parameter(fieldType, fieldName);  
//        setMethod.addParameter(param);  
//        setMethod.setVisibility(JavaVisibility.PUBLIC);  
//        setMethod.addBodyLine("this." + fieldName + "=" + fieldName + ";");  
//  
//        topLevelClass.addMethod(setMethod);  
//  
//        Method getMethod = new Method();  
//        getMethod.setName("get" + fieldName.toUpperCase().substring(0, 1)  
//                + fieldName.substring(1));  
//  
//        getMethod.setReturnType(fieldType);  
//        getMethod.setVisibility(JavaVisibility.PUBLIC);  
//        getMethod.addBodyLine("return this." + fieldName + ";");  
//  
//        System.out.println( "-------------------------fieldName:"+fieldName );
//        topLevelClass.addMethod(getMethod);  
//  
//    }  
    
    //affect model class
	public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass,
			IntrospectedTable introspectedTable) {
//		 String beanName = "PageBean";
//	        FullyQualifiedJavaType type = new FullyQualifiedJavaType(  
//	                introspectedTable.getBaseRecordType()); 
//	      
//		topLevelClass.addImportedType( type.getPackageName()+"."+beanName);
//		 boolean isCreate  = createPageBean("/home/pcjavanet/cdcWorkspace2/generatorForMobile/src/main/resources/pcjavanet/mobilesell/model/",beanName,type.getPackageName());
//		 FullyQualifiedJavaType intType = FullyQualifiedJavaType  
//	                .getIntInstance();  
////	        addField("pageIndex", intType, topLevelClass);  
////	        addField("pageSize", intType, topLevelClass);  
//	        Method getSkipCountMethod = new Method();  
//	        getSkipCountMethod.setName("getSkipRecordCount");  
//	  
//	        getSkipCountMethod.setReturnType(intType);  
//	        getSkipCountMethod.setVisibility(JavaVisibility.PUBLIC);  
//	        getSkipCountMethod  
//	                .addBodyLine("return (this.pageIndex-1)*this.pageSize;");  
//	  
//	        topLevelClass.addMethod(getSkipCountMethod);  
	          
		return true;
	}

	// model add
//	@Override
//	public boolean modelExampleClassGenerated(TopLevelClass topLevelClass,
//			IntrospectedTable introspectedTable) {
//		return true;
//	}
//
	// add Mapper java
	@Override
	public boolean clientGenerated(Interface interfaze,
			TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
		
		   Set<FullyQualifiedJavaType> importedTypes = new TreeSet<FullyQualifiedJavaType>();  
	        FullyQualifiedJavaType type = new FullyQualifiedJavaType(introspectedTable.getBaseRecordType());  
	        String beanName = "PageBean";
	        createPageBean("/home/pcjavanet/cdcWorkspace2/generatorForMobile/src/main/resources/pcjavanet/mobilesell/model/",beanName,type.getPackageName());
	        importedTypes.add(type);  
	        importedTypes.add(FullyQualifiedJavaType.getNewListInstance());  
	  
	        Method method = new Method();  
	        method.setVisibility(JavaVisibility.PUBLIC);  
	  
	        
	        FullyQualifiedJavaType sampleType=  new FullyQualifiedJavaType( type.getPackageName()+"."+type.getShortName() +"Example");
	        
	        
	        FullyQualifiedJavaType returnType = FullyQualifiedJavaType.getNewListInstance();  
	        FullyQualifiedJavaType listType;  
	        if (introspectedTable.getRules().generateBaseRecordClass()) {  
	            listType = new FullyQualifiedJavaType(introspectedTable .getBaseRecordType());  
	        } else if (introspectedTable.getRules().generatePrimaryKeyClass()) {  
	            listType = new FullyQualifiedJavaType(introspectedTable.getPrimaryKeyType());  
	        } else {  
	            throw new RuntimeException(getString("RuntimeError.12")); //$NON-NLS-1$  
	        }  
	  
	        importedTypes.add(listType);  
	        FullyQualifiedJavaType type3=  new FullyQualifiedJavaType( type.getPackageName()+"."+beanName );
	        importedTypes.add(type3);
	        returnType.addTypeArgument(listType);  
	        method.setReturnType(returnType);  
	  
//	        @Param("example") ColorExample example, @Param("pageBean") PageBean pageBean
	        method.setName("getOnePageBeans");  //selectPage
	        method.addParameter(new Parameter(sampleType, "example","@Param(\"example\")")); 
	        method.addParameter(new Parameter(type3, "pageBean","@Param(\"pageBean\")")); 
	        FullyQualifiedJavaType type2 = FullyQualifiedJavaType.getIntInstance();
//	        method.addParameter(new Parameter(type2, "offsetNumber")); 
//	        method.addParameter(new Parameter(type2, "limitNumber")); 
	  
	        interfaze.addImportedTypes(importedTypes);  
	        interfaze.addMethod(method);  
	        
	        Method method2 = new Method();  
	        method2.setVisibility(JavaVisibility.PUBLIC); 
	        method2.setName("getTotalRecords");
	        method2.addParameter(new Parameter(sampleType, "example","@Param(\"example\")")); 
	        method2.addParameter(new Parameter(type3, "pageBean","@Param(\"pageBean\")")); 
	        method2.setReturnType(type2);
	        interfaze.addMethod(method2);  
	        
	        
	        Method method3 = new Method();  
	        method3.setVisibility(JavaVisibility.PUBLIC); 
	        method3.setName("selectByExamplePage");
	        
	       
	        method3.addParameter(new Parameter(sampleType, "example","@Param(\"example\")")); 
	        method3.addParameter(new Parameter(type3, "pageBean","@Param(\"pageBean\")")); 
	        method3.setReturnType( returnType );
	        interfaze.addMethod(method3);  
	        
		return true;
	}
	
	private String createPageBean(String basoluteDir,String beanName,String packagePath	){
		StringBuffer buf2 = new StringBuffer();
		boolean isCreate = false ;
		if ( basoluteDir != null ){
			File dir = new File(basoluteDir);
			if (!dir.exists()){
				dir.mkdirs();
			}
		}
		String path = basoluteDir+beanName+".java";
		File f = new File( path );
		if ( f.exists()	){
		} else {
			
			StringBuffer buf = new StringBuffer();
			buf.append("package ").append(packagePath).append(";\r\n");
			buf.append("public class ").append( beanName).append("{\r\n");
			buf.append("   private int pageSize ;\r\n");
			buf.append("   private int startCount ; \r\n");
//			buf.append("   private String wherecondition = \" 1= 1 \"; \r\n");
			buf.append("   public void setPageSize(int pageSize){\r\n");
			buf.append( "      this.pageSize = pageSize;\r\n");
			buf.append("   }\r\n");
			buf.append("   public void setStartCount(int startCount){\r\n");
			buf.append( "      this.startCount = startCount;\r\n");
			buf.append("   }\r\n");
			buf.append("   public int getStartCount(){\r\n");
			buf.append( "     return  this.startCount ;\r\n");
			buf.append("   }\r\n");
			buf.append("   public int getPageSize(){\r\n");
			buf.append( "     return  this.pageSize ;\r\n");
			buf.append("   }\r\n");
//			buf.append("   public String getWherecondition(){\r\n");
//			buf.append( "     return  this.wherecondition ;\r\n");
//			buf.append("   }\r\n");
//			buf.append("   public void setWherecondition(String wherecondition){\r\n");
//			buf.append( "     this.wherecondition = wherecondition ;\r\n");
//			buf.append("   }\r\n");
			buf.append("}\r\n");
			;
			try {
				java.io.BufferedWriter bufwrite = new BufferedWriter(new FileWriter( path ));
				bufwrite.write( buf.toString() );
				bufwrite.close();
				isCreate = true;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return 	buf2.toString();
	}
//
//	// add xml content
	@Override
	public boolean sqlMapDocumentGenerated(Document document,
			IntrospectedTable introspectedTable) {
		 XmlElement parentElement = document.getRootElement();  
		   
 
		 FullyQualifiedJavaType type = new FullyQualifiedJavaType(           introspectedTable.getBaseRecordType()); 
		 String beanName = "PageBean";
		 String isCreate  = createPageBean("/home/pcjavanet/cdcWorkspace2/generatorForMobile/src/main/resources/pcjavanet/mobilesell/model/",beanName,type.getPackageName());
	        XmlElement answer = new XmlElement("select");   
//	  
	        answer.addAttribute(new Attribute("id",   "getTotalRecords")); 
	        answer.addAttribute(new Attribute("parameterType", "map"  )); 
	        answer.addAttribute(new Attribute("resultType",   "java.lang.Integer")); 
	        StringBuffer buf = new StringBuffer();
	        buf.append(" SELECt COUNT(dbid)  FROM     ").append( type.getShortName() ).append( " \r\n");
	        buf.append("\r\n		<if test=\"_parameter != null\" >\r\n");
			buf.append( "			<include refid=\"Update_By_Example_Where_Clause\" />\r\n");
			buf.append(" 		</if>\r\n");
	        answer.addElement( new TextElement(buf.toString()));
	        parentElement.addElement(answer);
	        
	        
	        XmlElement answer2 = new XmlElement("select");   
//	  
	        answer2.addAttribute(new Attribute("id",   "getOnePageBeans")); 
	        answer2.addAttribute(new Attribute("parameterType", "map"  )); 
	        answer2.addAttribute(new Attribute("resultMap","BaseResultMap"));
	        StringBuffer buf2 = new StringBuffer();
			buf2.append(" 	SELECt *  FROM     ").append( type.getShortName() );
			buf2.append("\r\n		<if test=\"_parameter != null\" >\r\n");
			buf2.append( "			<include refid=\"Update_By_Example_Where_Clause\" />\r\n");
			buf2.append(" 		</if>\r\n");
			buf2.append(" 		ORDER BY dbid LIMIT #{pageBean.pageSize,jdbcType=INTEGER}    OFFSET   #{pageBean.startCount,jdbcType=INTEGER} " );
	        answer2.addElement( new TextElement(buf2.toString()));
	        parentElement.addElement(answer2);
	        
	        XmlElement answer3 = new XmlElement("select");   
	        answer3.addAttribute(new Attribute("id",   "selectByExamplePage")); 
	        answer3.addAttribute(new Attribute("parameterType",  "map")); 
	        StringBuffer buf3 = new StringBuffer();
			buf3.append(" 	SELECt *  FROM     ").append( type.getShortName() );
			buf3.append("\r\n		<if test=\"_parameter != null\" >\r\n");
			buf3.append( "			<include refid=\"Update_By_Example_Where_Clause\" />\r\n");
			buf3.append(" 		</if>\r\n");
			buf3.append(" 		ORDER BY dbid LIMIT #{pageBean.pageSize,jdbcType=INTEGER}    OFFSET   #{pageBean.startCount,jdbcType=INTEGER} " );
			answer3.addElement( new TextElement(buf3.toString()));
			parentElement.addElement(answer3);
	        
		return true;
	}
}
